package com.chengqs.rapid.core.netty.processor.filter.pre;

import com.chengqs.rapid.common.config.DubboServiceInvoker;
import com.chengqs.rapid.common.constants.ProcessorFilterConstants;
import com.chengqs.rapid.common.constants.RapidProtocol;
import com.chengqs.rapid.core.context.AttributeKey;
import com.chengqs.rapid.core.context.Context;
import com.chengqs.rapid.core.context.RapidContext;
import com.chengqs.rapid.core.context.RapidRequest;
import com.chengqs.rapid.core.netty.processor.filter.AbstractEntryProcessorFilter;
import com.chengqs.rapid.core.netty.processor.filter.Filter;
import com.chengqs.rapid.core.netty.processor.filter.FilterConfig;
import com.chengqs.rapid.core.netty.processor.filter.ProcessorFilterType;
import lombok.Getter;
import lombok.Setter;

/**
 * <B>主类名称：</B>TimeoutPreFilter<BR>
 * <B>概要说明：</B>超时的前置过滤器<BR>
 *
 * @author: chengqs
 * @create: 2025-03-15 17:55:49
 **/
@Filter(
        id = ProcessorFilterConstants.TIMEOUT_PRE_FILTER_ID,
        name = ProcessorFilterConstants.TIMEOUT_PRE_FILTER_NAME,
        value = ProcessorFilterType.PRE,
        order = ProcessorFilterConstants.TIMEOUT_PRE_FILTER_ORDER
)
public class TimeoutPreFilter extends AbstractEntryProcessorFilter<TimeoutPreFilter.Config> {

    public TimeoutPreFilter() {
        super(TimeoutPreFilter.Config.class);
    }

    /**
     * 超时的过滤器核心方法实现
     * @param context
     * @param args
     * @throws Throwable
     */
    @Override
    public void entry(Context context, Object... args) throws Throwable {
        try {
            RapidContext rapidContext = (RapidContext) context;
            String protocol = rapidContext.getProtocol();
            TimeoutPreFilter.Config config = (TimeoutPreFilter.Config) args[0];
            switch (protocol) {
                case RapidProtocol.HTTP:
                    RapidRequest rapidRequest = rapidContext.getRequest();
                    rapidRequest.setRequestTimeout(config.getTimeout());
                    break;
                case RapidProtocol.DUBBO:
                    DubboServiceInvoker dubboServiceInvoker = (DubboServiceInvoker)rapidContext.getRequiredAttribute(AttributeKey.DUBBO_INVOKER);
                    dubboServiceInvoker.setTimeout(config.getTimeout());
                    break;
                default:
                    break;
            }
        } finally {
            // 非常重要的，一定要记得：驱动我们的过滤器链表
            super.fireNext(context, args);
        }
    }

    @Getter
    @Setter
    public static class Config extends FilterConfig {
        private Integer timeout;
    }
}
